/**
 * 
 */
package bancosys.tec.security.impl.proxy;

import java.lang.reflect.Method;
import java.util.Collection;

import jmine.tec.proxy.chain.ChainElement;
import jmine.tec.proxy.chain.InvocationChain;
import bancosys.tec.security.annotation.Task;
import bancosys.tec.security.authorization.Permission;
import bancosys.tec.security.authorization.TaskPermission;

/**
 * @author gigante
 */
public class TarefaAuthorizationChainElemet implements ChainElement {

    private Collection<Permission> permissoes;

    /**
     * C'tor
     * 
     * @param permissoes a coleção de permissões
     */
    public TarefaAuthorizationChainElemet(Collection<Permission> permissoes) {
        this.permissoes = permissoes;
    }

    /**
     * @see br.com.maps.util.proxy.chain.ChainElement#aroundInvoke(br.com.maps.util.proxy.chain.InvocationChain)
     * @param chain o chain
     * @return o return do chain
     * @throws Throwable SecurityException
     */
    public Object aroundInvoke(InvocationChain chain) throws Throwable {

        Method method = chain.getInvokingMethod();
        if (method.isAnnotationPresent(Task.class)) {

            Task annotation = method.getAnnotation(Task.class);
            String nomeTarefa = annotation.nome();

            for (Permission permission : this.permissoes) {
                if (permission.match(TaskPermission.class, nomeTarefa)) {
                    return chain.proceed();
                }
            }
            throw new SecurityException("Access denied for task: " + nomeTarefa);
        }

        return chain.proceed();
    }

}
